#pragma once
#include "..\Core\System.h"
#include "Panel.h"

namespace GUIToolkit
{
	class HwndHost
		: public Panel
	{
	private:
		HWND hWnd;
		WNDPROC oldWndProc;

		void SubClass();

		static LRESULT WINAPI HostProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

	protected:
		virtual LRESULT WndProc(UINT msg, WPARAM wParam, LPARAM lParam, bool& handled);
		virtual void OnPropertyChanged(PROPERTY p);

		void Synchronize();

		virtual void OnAttach(){}
		virtual void OnDetach(){}

	public:
		HwndHost();
		void Attach(HWND hWnd);
		virtual void Create( LPCTSTR text, LPCTSTR cls = NULL, HWND parent = NULL, int style = WS_OVERLAPPEDWINDOW, int exstyle = WS_EX_APPWINDOW, RectF* rect = NULL );
		void Detach();

		bool IsAttached() const { return ::IsWindow(this->hWnd); }

		HWND GetHandle() const { return this->hWnd; }

		LRESULT SendMessage(UINT msg, WPARAM wParam, LPARAM lParam) const
		{
			return ::SendMessage(this->hWnd, msg, wParam, lParam);
		}
		BOOL PostMessage(UINT msg, WPARAM wParam, LPARAM lParam) const
		{
			return ::PostMessage(this->hWnd, msg, wParam, lParam);
		}

		virtual bool Focusable() const { return true; }

		virtual void Update(RectF* rect = NULL);

		SizeF GetClientSize() const
		{
			RECT r;
			::GetClientRect(this->hWnd, &r);
			return SizeF(r.right - r.left, r.bottom - r.top);
		}
		void SetClientSize(const SizeF &size) const
		{
			this->SetClientSize(size.Width, size.Height);
		}
		void SetClientSize(float width, float height) const;

		int GetWindowStyle() const
		{
			return ::GetWindowLong(hWnd, GWL_STYLE);
		}
		void SetWindowStyle(int value)
		{
			::SetWindowLong(hWnd, GWL_STYLE, value);
		}

		int GetWindowExStyle() const
		{
			return ::GetWindowLong(hWnd, GWL_EXSTYLE);
		}
		void SetWindowExStyle(int value)
		{
			::SetWindowLong(hWnd, GWL_EXSTYLE, value);
		}

		void Close();

		~HwndHost(void);
	};
}